#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
单例模式 (Singleton Pattern) - Python实现详解

🎯 模式概述：
单例模式确保一个类只有一个实例，并提供全局访问点。在Python中有多种优雅的实现方式，
比Java的实现更加简洁和Pythonic。

📚 Java vs Python 对比：

Java实现（线程安全的懒汉式）：
public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

Python的优势：
1. 多种实现方式：装饰器、元类、__new__方法
2. 线程安全更容易保证
3. 代码更简洁易读
4. 支持继承和多态

💡 关键理解：
Python的模块本身就是单例，import机制保证了模块只被加载一次。
很多时候直接使用模块级别的变量和函数就足够了。
"""

import threading
import time
from typing import Optional, Any, Dict
from functools import wraps
from abc import ABC, abstractmethod


# ==================== 方法1: 装饰器实现 ====================
# 这是最Pythonic的实现方式，Java中没有对应的简洁写法

def singleton(cls):
    """
    单例装饰器 - Python独有的优雅实现
    
    Java对比：
    Java需要在类内部实现单例逻辑，代码分散在构造函数、静态方法等多处
    Python装饰器将单例逻辑完全外置，类本身保持纯净
    
    优势：
    1. 类定义保持简洁
    2. 可以装饰任何类
    3. 线程安全（利用字典的原子操作）
    4. 支持参数传递
    """
    instances = {}  # 存储实例的字典
    lock = threading.Lock()  # 线程锁，对应Java的synchronized
    
    @wraps(cls)
    def get_instance(*args, **kwargs):
        # 双重检查锁定模式，与Java实现类似
        if cls not in instances:
            with lock:  # Python的with语句比Java的synchronized更优雅
                if cls not in instances:
                    instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    
    return get_instance


@singleton
class DatabaseConnection:
    """
    数据库连接单例 - 使用装饰器实现
    
    Java等价类：
    @Component
    @Scope("singleton")
    public class DatabaseConnection {
        private String connectionString;
        
        public DatabaseConnection() {
            this.connectionString = "jdbc:mysql://localhost:3306/db";
        }
    }
    """
    
    def __init__(self, connection_string: str = "postgresql://localhost:5432/mydb"):
        self.connection_string = connection_string
        self.is_connected = False
        print(f"🔗 创建数据库连接: {connection_string}")
    
    def connect(self) -> None:
        """连接数据库"""
        if not self.is_connected:
            print(f"📡 连接到数据库: {self.connection_string}")
            self.is_connected = True
        else:
            print("⚠️ 数据库已连接")
    
    def disconnect(self) -> None:
        """断开数据库连接"""
        if self.is_connected:
            print("🔌 断开数据库连接")
            self.is_connected = False


# ==================== 方法2: 元类实现 ====================
# 这是Python特有的高级特性，Java中没有直接对应

class SingletonMeta(type):
    """
    单例元类 - Python的高级特性
    
    Java对比：
    Java没有元类概念，这是Python独有的强大特性
    元类控制类的创建过程，比Java的反射更强大
    
    工作原理：
    1. 元类控制类的实例化过程
    2. __call__方法在创建实例时被调用
    3. 实现了真正的单例控制
    """
    
    _instances: Dict[type, Any] = {}  # 类型注解，对应Java的泛型
    _lock = threading.Lock()
    
    def __call__(cls, *args, **kwargs):
        """
        控制实例创建 - 对应Java的构造函数调用
        
        Java中需要在构造函数中实现单例逻辑：
        private Singleton() {
            if (instance != null) {
                throw new RuntimeException("Use getInstance() method");
            }
        }
        """
        if cls not in cls._instances:
            with cls._lock:
                if cls not in cls._instances:
                    cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]


class ConfigManager(metaclass=SingletonMeta):
    """
    配置管理器单例 - 使用元类实现
    
    Java等价类：
    public class ConfigManager {
        private static volatile ConfigManager instance;
        private Properties config;
        
        private ConfigManager() {
            config = new Properties();
            loadConfig();
        }
        
        public static ConfigManager getInstance() {
            if (instance == null) {
                synchronized (ConfigManager.class) {
                    if (instance == null) {
                        instance = new ConfigManager();
                    }
                }
            }
            return instance;
        }
    }
    """
    
    def __init__(self):
        if not hasattr(self, 'initialized'):  # 防止重复初始化
            self.config: Dict[str, Any] = {}
            self.load_config()
            self.initialized = True
    
    def load_config(self) -> None:
        """加载配置 - 对应Java的Properties.load()"""
        print("📋 加载应用配置...")
        self.config = {
            'database_url': 'postgresql://localhost:5432/myapp',
            'redis_url': 'redis://localhost:6379/0',
            'debug_mode': True,
            'max_connections': 100
        }
    
    def get(self, key: str, default: Any = None) -> Any:
        """获取配置值 - 对应Java的getProperty()"""
        return self.config.get(key, default)
    
    def set(self, key: str, value: Any) -> None:
        """设置配置值 - 对应Java的setProperty()"""
        self.config[key] = value
        print(f"⚙️ 更新配置: {key} = {value}")


# ==================== 方法3: __new__方法实现 ====================
# 这种方式最接近Java的实现逻辑

class Logger:
    """
    日志记录器单例 - 使用__new__方法实现
    
    Java等价实现：
    public class Logger {
        private static Logger instance;
        private PrintWriter writer;
        
        private Logger() {
            try {
                writer = new PrintWriter(new FileWriter("app.log", true));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        
        public static synchronized Logger getInstance() {
            if (instance == null) {
                instance = new Logger();
            }
            return instance;
        }
    }
    
    这种Python实现更接近Java的逻辑，但不如装饰器优雅
    """
    
    _instance: Optional['Logger'] = None
    _lock = threading.Lock()
    
    def __new__(cls) -> 'Logger':
        """
        控制实例创建 - 对应Java的getInstance()方法
        
        __new__是Python的特殊方法，在__init__之前调用
        这是最接近Java单例实现逻辑的方式
        """
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        """初始化方法 - 注意防止重复初始化"""
        if not hasattr(self, 'initialized'):
            self.log_file = "app.log"
            self.initialized = True
            print(f"📝 初始化日志记录器: {self.log_file}")
    
    def log(self, level: str, message: str) -> None:
        """记录日志 - 对应Java的log方法"""
        timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
        log_entry = f"[{timestamp}] {level.upper()}: {message}"
        print(f"📄 {log_entry}")
        # 实际项目中这里会写入文件
    
    def info(self, message: str) -> None:
        """信息日志"""
        self.log('info', message)
    
    def error(self, message: str) -> None:
        """错误日志"""
        self.log('error', message)


# ==================== 方法4: 模块级单例 ====================
# 这是最Pythonic的方式，Java中没有对应概念

class _CacheManager:
    """
    缓存管理器 - 私有类，只在模块内部使用
    
    Java对比：
    Java需要复杂的单例实现，而Python的模块导入机制天然保证单例
    这是最符合Python哲学的实现方式
    """
    
    def __init__(self):
        self.cache: Dict[str, Any] = {}
        print("🗄️ 初始化缓存管理器")
    
    def get(self, key: str) -> Optional[Any]:
        """获取缓存值"""
        return self.cache.get(key)
    
    def set(self, key: str, value: Any, ttl: int = 3600) -> None:
        """设置缓存值"""
        self.cache[key] = {
            'value': value,
            'timestamp': time.time(),
            'ttl': ttl
        }
        print(f"💾 缓存设置: {key}")
    
    def clear(self) -> None:
        """清空缓存"""
        self.cache.clear()
        print("🧹 缓存已清空")


# 模块级实例 - 这就是单例！
cache_manager = _CacheManager()


# ==================== 企业级单例基类 ====================
# 提供可继承的单例基类，类似Java的抽象单例类

class SingletonBase(ABC):
    """
    单例基类 - 企业级实现
    
    Java等价抽象类：
    public abstract class SingletonBase {
        private static final Map<Class<?>, Object> instances = new ConcurrentHashMap<>();
        
        @SuppressWarnings("unchecked")
        public static <T extends SingletonBase> T getInstance(Class<T> clazz) {
            return (T) instances.computeIfAbsent(clazz, k -> {
                try {
                    return k.getDeclaredConstructor().newInstance();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
        }
        
        protected abstract void initialize();
    }
    
    Python的优势：
    1. 元类自动处理单例逻辑
    2. 类型安全的泛型支持
    3. 抽象方法强制子类实现
    4. 更简洁的继承语法
    """
    
    _instances: Dict[type, 'SingletonBase'] = {}
    _lock = threading.Lock()
    
    def __new__(cls, *args, **kwargs):
        if cls not in cls._instances:
            with cls._lock:
                if cls not in cls._instances:
                    instance = super().__new__(cls)
                    cls._instances[cls] = instance
        return cls._instances[cls]
    
    def __init__(self, *args, **kwargs):
        if not hasattr(self, '_initialized'):
            self.initialize(*args, **kwargs)
            self._initialized = True
    
    @abstractmethod
    def initialize(self, *args, **kwargs) -> None:
        """子类必须实现的初始化方法"""
        pass


class SessionManager(SingletonBase):
    """
    会话管理器 - 继承单例基类
    
    Java等价类：
    public class SessionManager extends SingletonBase {
        private Map<String, Session> sessions;
        
        @Override
        protected void initialize() {
            sessions = new ConcurrentHashMap<>();
        }
        
        public void createSession(String userId) {
            sessions.put(userId, new Session(userId));
        }
    }
    """
    
    def initialize(self) -> None:
        """实现抽象方法"""
        self.sessions: Dict[str, Dict[str, Any]] = {}
        print("👥 初始化会话管理器")
    
    def create_session(self, user_id: str) -> str:
        """创建用户会话"""
        session_id = f"session_{user_id}_{int(time.time())}"
        self.sessions[session_id] = {
            'user_id': user_id,
            'created_at': time.time(),
            'last_access': time.time()
        }
        print(f"🎫 创建会话: {session_id}")
        return session_id
    
    def get_session(self, session_id: str) -> Optional[Dict[str, Any]]:
        """获取会话信息"""
        return self.sessions.get(session_id)
    
    def remove_session(self, session_id: str) -> bool:
        """移除会话"""
        if session_id in self.sessions:
            del self.sessions[session_id]
            print(f"🗑️ 移除会话: {session_id}")
            return True
        return False


# ==================== 测试和演示 ====================

def demonstrate_singleton_patterns():
    """
    演示各种单例模式实现
    
    🎯 学习重点：
    1. 理解Python多种单例实现方式
    2. 对比Java实现的差异和优势
    3. 选择合适的实现方式
    4. 理解线程安全和性能考虑
    """
    print("\n" + "="*60)
    print("🏗️ 单例模式 (Singleton Pattern) 演示")
    print("="*60)
    
    # 1. 装饰器单例测试
    print("\n1️⃣ 装饰器单例测试")
    print("-" * 30)
    
    db1 = DatabaseConnection()
    db2 = DatabaseConnection("mysql://localhost:3306/test")
    
    print(f"db1 is db2: {db1 is db2}")  # True - 同一个实例
    print(f"db1 连接字符串: {db1.connection_string}")
    print(f"db2 连接字符串: {db2.connection_string}")
    
    db1.connect()
    db2.connect()  # 不会重复连接
    
    # 2. 元类单例测试
    print("\n2️⃣ 元类单例测试")
    print("-" * 30)
    
    config1 = ConfigManager()
    config2 = ConfigManager()
    
    print(f"config1 is config2: {config1 is config2}")  # True
    
    config1.set('new_setting', 'test_value')
    print(f"config2获取设置: {config2.get('new_setting')}")
    
    # 3. __new__方法单例测试
    print("\n3️⃣ __new__方法单例测试")
    print("-" * 30)
    
    logger1 = Logger()
    logger2 = Logger()
    
    print(f"logger1 is logger2: {logger1 is logger2}")  # True
    
    logger1.info("这是一条信息日志")
    logger2.error("这是一条错误日志")
    
    # 4. 模块级单例测试
    print("\n4️⃣ 模块级单例测试")
    print("-" * 30)
    
    cache_manager.set('user:123', {'name': 'Alice', 'age': 30})
    user_data = cache_manager.get('user:123')
    print(f"缓存数据: {user_data}")
    
    # 5. 继承单例基类测试
    print("\n5️⃣ 继承单例基类测试")
    print("-" * 30)
    
    session_mgr1 = SessionManager()
    session_mgr2 = SessionManager()
    
    print(f"session_mgr1 is session_mgr2: {session_mgr1 is session_mgr2}")  # True
    
    session_id = session_mgr1.create_session('user123')
    session_data = session_mgr2.get_session(session_id)
    print(f"会话数据: {session_data}")
    
    # 6. 线程安全测试
    print("\n6️⃣ 线程安全测试")
    print("-" * 30)
    
    def create_logger_instance(thread_id: int):
        """在线程中创建Logger实例"""
        logger = Logger()
        logger.info(f"线程 {thread_id} 创建的Logger实例: {id(logger)}")
        return logger
    
    # 创建多个线程测试单例
    threads = []
    for i in range(3):
        thread = threading.Thread(target=create_logger_instance, args=(i,))
        threads.append(thread)
        thread.start()
    
    # 等待所有线程完成
    for thread in threads:
        thread.join()
    
    print("\n📊 单例模式总结")
    print("-" * 30)
    print("✅ 装饰器方式: 最Pythonic，推荐用于简单场景")
    print("✅ 元类方式: 高级特性，适合框架开发")
    print("✅ __new__方式: 最接近Java实现，易于理解")
    print("✅ 模块级方式: 最简单，适合工具类")
    print("✅ 继承基类: 企业级应用，支持多态")


def performance_comparison():
    """
    性能对比测试
    
    对比不同单例实现方式的性能差异
    """
    print("\n" + "="*60)
    print("⚡ 单例模式性能对比")
    print("="*60)
    
    import timeit
    
    # 测试装饰器单例性能
    decorator_time = timeit.timeit(
        lambda: DatabaseConnection(),
        number=10000
    )
    
    # 测试元类单例性能
    metaclass_time = timeit.timeit(
        lambda: ConfigManager(),
        number=10000
    )
    
    # 测试__new__单例性能
    new_method_time = timeit.timeit(
        lambda: Logger(),
        number=10000
    )
    
    print(f"装饰器单例 (10000次): {decorator_time:.4f}秒")
    print(f"元类单例 (10000次): {metaclass_time:.4f}秒")
    print(f"__new__单例 (10000次): {new_method_time:.4f}秒")
    
    print("\n💡 性能建议:")
    print("- 装饰器方式通常性能最好")
    print("- 元类方式功能最强大但性能稍差")
    print("- __new__方式性能中等，最易理解")


if __name__ == "__main__":
    # 运行演示
    demonstrate_singleton_patterns()
    
    # 性能对比（可选）
    # performance_comparison()
    
    print("\n🎉 单例模式演示完成！")
    print("\n📚 学习要点回顾:")
    print("1. Python提供多种优雅的单例实现方式")
    print("2. 装饰器是最Pythonic的实现")
    print("3. 模块级单例是最简单的方式")
    print("4. 选择实现方式要考虑场景和性能")
    print("5. Python的单例比Java实现更简洁")